#include <stdint.h>
/*
	numbered.cpp - Library for arduino to play numbered musical notation
	Created by ZhuPingQi September 13, 2023.
  416803633@qq.com
  https://space.bilibili.com/17698817
  https://gitee.com/zhupingqi
	Released into the public domain.
*/

#include "Arduino.h"

#ifndef __NOTE_NMN__
#define __NOTE_NMN__

#define ND 0
#define N4D7 uint32_t(31) << 16
#define N3D1 uint32_t(33) << 16
#define N3D1S uint32_t(35) << 16
#define N3D2 uint32_t(37) << 16
#define N3D2S uint32_t(39) << 16
#define N3D3 uint32_t(41) << 16
#define N3D4 uint32_t(44) << 16
#define N3D4S uint32_t(46) << 16
#define N3D5 uint32_t(49) << 16
#define N3D5S uint32_t(52) << 16
#define N3D6 uint32_t(55) << 16
#define N3D6S uint32_t(58) << 16
#define N3D7 uint32_t(62) << 16
#define N2D1 uint32_t(65) << 16
#define N2D1S uint32_t(69) << 16
#define N2D2 uint32_t(73) << 16
#define N2D2S uint32_t(78) << 16
#define N2D3 uint32_t(82) << 16
#define N2D4 uint32_t(87) << 16
#define N2D4S uint32_t(93) << 16
#define N2D5 uint32_t(98) << 16
#define N2D5S uint32_t(104) << 16
#define N2D6 uint32_t(110) << 16
#define N2D6S uint32_t(117) << 16
#define N2D7 uint32_t(123) << 16
#define ND1 uint32_t(131) << 16
#define ND1S uint32_t(139) << 16
#define ND2 uint32_t(147) << 16
#define ND2S uint32_t(156) << 16
#define ND3 uint32_t(165) << 16
#define ND4 uint32_t(175) << 16
#define ND4S uint32_t(185) << 16
#define ND5 uint32_t(196) << 16
#define ND5S uint32_t(208) << 16
#define ND6 uint32_t(220) << 16
#define ND6S uint32_t(233) << 16
#define ND7 uint32_t(247) << 16
#define N1 uint32_t(262) << 16
#define N1S uint32_t(277) << 16
#define N2 uint32_t(294) << 16
#define N2S uint32_t(311) << 16
#define N3 uint32_t(330) << 16
#define N4 uint32_t(349) << 16
#define N4S uint32_t(370) << 16
#define N5 uint32_t(392) << 16
#define N5S uint32_t(415) << 16
#define N6 uint32_t(440) << 16
#define N6S uint32_t(466) << 16
#define N7 uint32_t(494) << 16
#define NG1 uint32_t(523) << 16
#define NG1S uint32_t(554) << 16
#define NG2 uint32_t(587) << 16
#define NG2S uint32_t(622) << 16
#define NG3 uint32_t(659) << 16
#define NG4 uint32_t(698) << 16
#define NG4S uint32_t(740) << 16
#define NG5 uint32_t(784) << 16
#define NG5S uint32_t(831) << 16
#define NG6 uint32_t(880) << 16
#define NG6S uint32_t(932) << 16
#define NG7 uint32_t(988) << 16
#define N2G1 uint32_t(1047) << 16
#define N2G1S uint32_t(1109) << 16
#define N2G2 uint32_t(1175) << 16
#define N2G2S uint32_t(1245) << 16
#define N2G3 uint32_t(1319) << 16
#define N2G4 uint32_t(1397) << 16
#define N2G4S uint32_t(1480) << 16
#define N2G5 uint32_t(1568) << 16
#define N2G5S uint32_t(1661) << 16
#define N2G6 uint32_t(1760) << 16
#define N2G6S uint32_t(1865) << 16
#define N2G7 uint32_t(1976) << 16
#define N3G1 uint32_t(2093) << 16
#define N3G1S uint32_t(2217) << 16
#define N3G2 uint32_t(2349) << 16
#define N3G2S uint32_t(2489) << 16
#define N3G3 uint32_t(2637) << 16
#define N3G4 uint32_t(2794) << 16
#define N3G4S uint32_t(2960) << 16
#define N3G5 uint32_t(3136) << 16
#define N3G5S uint32_t(3322) << 16
#define N3G6 uint32_t(3520) << 16
#define N3G6S uint32_t(3729) << 16
#define N3G7 uint32_t(3951) << 16
#define N4G1 uint32_t(4186) << 16
#define N4G1S uint32_t(4435) << 16
#define N4G2 uint32_t(4699) << 16
#define N4G2S uint32_t(4978) << 16

#define PERSIST_1 uint16_t(1 << 8)
#define PERSIST_2 uint16_t(2 << 8)
#define PERSIST_3 uint16_t(3 << 8)
#define PERSIST_4 uint16_t(4 << 8)
#define PERSIST_5 uint16_t(5 << 8)
#define PERSIST_6 uint16_t(6 << 8)
#define PERSIST_7 uint16_t(7 << 8)
#define PERSIST_8 uint16_t(8 << 8)
#define PERSIST_9 uint16_t(9 << 8)
#define PERSIST_10 uint16_t(10 << 8)

#endif

class NumberedMusicalNotation {
  // public属性，外部可以访问
public:
  // 构造函数
  NumberedMusicalNotation(uint8_t beats, uint8_t notesBeat, uint8_t pin);
  // 析构函数
  ~NumberedMusicalNotation();

  init();
  play(uint32_t notes[], int size);

private:
  uint8_t _beats;
  uint8_t _pin;
  uint16_t _duration;
  uint16_t _noteDelay;

  int getNoteDuration(uint16_t mask);
};